package app.modules.infrastructure.profile.business.service;

import app.modules.common.constant.TenantConstants;
import app.modules.common.enums.EnableFlagEnum;
import app.modules.common.exception.UnauthorizedDataAccessException;
import app.modules.common.exception.UnauthorizedDataCreateException;
import app.modules.common.util.auth.CurrentSubjectUtil;
import app.modules.infrastructure.profile.constant.ProfileMsgConstants;
import app.modules.infrastructure.profile.dto.web.WebProfileItemDTO;
import app.modules.infrastructure.profile.dto.web.WebProfileItemQueryDTO;
import app.modules.infrastructure.profile.persistence.dao.ProfileItemDAO;
import app.modules.infrastructure.profile.persistence.entity.ProfileItemEO;
import app.modules.infrastructure.profile.util.conversion.ProfileItemConvertUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jasmine.framework.common.exception.BusinessException;
import jasmine.framework.common.exception.DataNotFoundException;
import jasmine.framework.common.util.CheckUtil;
import jasmine.framework.common.util.CollectionUtil;
import jasmine.framework.common.util.I18nUtil;
import jasmine.framework.common.util.MapperUtil;
import jasmine.framework.common.util.ObjectUtil;
import jasmine.framework.context.CurrentSubject;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;

/**
 * @author mh.z
 */
@Service
public class ProfileItemService implements IProfileItemService {
    private ProfileItemDAO profileItemDAO;

    public ProfileItemService(ProfileItemDAO profileItemDAO) {
        this.profileItemDAO = profileItemDAO;
    }

    /**
     * 分页查询配置项
     *
     * @param queryDTO
     * @param page
     * @return
     */
    public List<WebProfileItemDTO> pageWebProfileItemDTOsByCond(WebProfileItemQueryDTO queryDTO, Page page) {
        CheckUtil.notNull(queryDTO, "queryDTO null");
        CheckUtil.notNull(page, "page null");

        boolean adminFlag = CurrentSubjectUtil.isAdminUser();
        List<WebProfileItemDTO> recordList = profileItemDAO.pageWebProfileItemDTOsByCond(queryDTO,
                adminFlag, page);
        populateWebProfileItemDTOs(recordList);

        return recordList;
    }

    /**
     * 填充数据
     *
     * @param records
     */
    protected void populateWebProfileItemDTOs(List<WebProfileItemDTO> records) {
        if (CollectionUtil.isEmpty(records)) {
            return;
        }

        records.forEach((record) -> {
            EnableFlagEnum enableFlagEnum = EnableFlagEnum.parseValue(record.getEnableFlag());
            record.setEnableFlagDesc(I18nUtil.getMessage(enableFlagEnum));
        });
    }

    /**
     * 查找指定 ID 的记录
     *
     * @param id
     * @return
     */
    public WebProfileItemDTO getWebProfileItemDtoById(Long id) {
        CheckUtil.notNull(id, "id null");

        ProfileItemEO profileItemEO = profileItemDAO.getById(id);
        WebProfileItemDTO webProfileItemDTO = ProfileItemConvertUtil.profileItemEO2WebProfileItemDTO(profileItemEO);
        populateWebProfileItemDTOs(Collections.singletonList(webProfileItemDTO));

        return webProfileItemDTO;
    }

    /**
     * 保存记录
     *
     * @param saveDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public WebProfileItemDTO saveProfileItem(WebProfileItemDTO saveDTO) {
        CheckUtil.notNull(saveDTO, "saveDTO null");

        if (ObjectUtil.notEqual(TenantConstants.SYSTEM_TENANT_ID, CurrentSubject.getTenantId())) {
            throw new UnauthorizedDataCreateException()
                    .withErrorDetail(ProfileItemEO.class, null);
        }

        String profileItemCode = saveDTO.getItemCode();
        long profileItemCodeCount = profileItemDAO.countByProfileItemCode(profileItemCode, null);

        if (profileItemCodeCount > 0) {
            throw new BusinessException(ProfileMsgConstants.THE_PROFILE_ITEM_CODE_ALREADY_EXISTS,
                    new Object[]{profileItemCode});
        }

        ProfileItemEO profileItemEO = new ProfileItemEO();
        MapperUtil.mapFields(saveDTO, profileItemEO);
        profileItemEO.setTenantId(CurrentSubject.getTenantId());
        // 保存记录
        profileItemDAO.save(profileItemEO);

        return getWebProfileItemDtoById(profileItemEO.getId());
    }

    /**
     * 更新记录
     *
     * @param updateDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public WebProfileItemDTO updateProfileItem(WebProfileItemDTO updateDTO) {
        CheckUtil.notNull(updateDTO, "updateDTO null");
        Long id = CheckUtil.notNull(updateDTO.getId(), "updateDTO.id null");

        if (ObjectUtil.notEqual(TenantConstants.SYSTEM_TENANT_ID, CurrentSubject.getTenantId())) {
            throw new UnauthorizedDataAccessException()
                    .withErrorDetail(ProfileItemEO.class, id, null);
        }

        String profileItemCode = updateDTO.getItemCode();
        long profileItemCodeCount = profileItemDAO.countByProfileItemCode(profileItemCode,
                Collections.singletonList(id));

        if (profileItemCodeCount > 0) {
            throw new BusinessException(ProfileMsgConstants.THE_PROFILE_ITEM_CODE_ALREADY_EXISTS,
                    new Object[]{profileItemCode});
        }

        ProfileItemEO profileItemEO = profileItemDAO.getById(id);
        if (profileItemEO == null) {
            throw new DataNotFoundException(ProfileItemEO.class, id);
        }

        MapperUtil.mapFields(updateDTO, profileItemEO);
        // 更新记录
        profileItemDAO.strictUpdateById(profileItemEO);

        return getWebProfileItemDtoById(id);
    }

}
